﻿Public Class Section
  Private _name As String = ""
  Private _valuePair As New Dictionary(Of String, ValueTristate)(StringComparer.OrdinalIgnoreCase)

  Friend Class ValueTristate
    Private _value As String = String.Empty
    Private _tristate As Boolean = False

    Public Property Value() As String
      Get
        Return Me._value
      End Get
      Set(ByVal value As String)
        Me._value = value
      End Set
    End Property

    Public Property Tristate() As Boolean
      Get
        Return Me._tristate
      End Get
      Set(ByVal value As Boolean)
        Me._tristate = value
      End Set
    End Property
  End Class

  Friend Sub SetName(ByVal newname As String)
    Me._name = newname
  End Sub

  Public ReadOnly Property Name() As String
    Get
      Return Me._name
    End Get
  End Property

  Public Sub Clear()
    Me._valuePair.Clear()
  End Sub

  Public Sub Add(ByVal key As String, ByVal value As String)
    If Me._valuePair.ContainsKey(key) Then
      Me._valuePair(key).Value = CStr(IIf(value Is Nothing, "", value))
    Else
      Dim vts As New ValueTristate
      vts.Value = CStr(IIf(value Is Nothing, "", value))
      Me._valuePair.Add(key, vts)
    End If
  End Sub

  Public Sub Add(ByVal key As String, ByVal value As Integer)
    Me.Add(key, value.ToString)
  End Sub

  Public Sub Add(ByVal key As String, ByVal value As Long)
    Me.Add(key, value.ToString)
  End Sub

  Public Sub Add(ByVal key As String, ByVal value As Boolean)
    If value Then
      Me.Add(key, "1")
    Else
      Me.Add(key, "0")
    End If
  End Sub

  Public Function Remove(ByVal key As String) As Boolean
    Return Me._valuePair.Remove(key)
  End Function

  Public ReadOnly Property Keys() As String()
    Get
      Return Me._valuePair.Keys.ToArray
    End Get
  End Property

  Public Property StringValue(ByVal key As String) As String
    Get
      If Me._valuePair.ContainsKey(key) Then
        Return Me._valuePair(key).Value
      Else
        Return Nothing
      End If
    End Get
    Set(ByVal value As String)
      If Me._valuePair.ContainsKey(key) Then
        If value IsNot Nothing Then
          Me._valuePair(key).Value = value
        Else
          Me.Remove(key)
        End If
      Else
        Me.Add(key, value)
      End If
    End Set
  End Property

  Public ReadOnly Property StringValueNoNull(ByVal key As String, Optional ByVal defaultValue As String = "") As String
    Get
      If Me._valuePair.ContainsKey(key) Then
        Return Me._valuePair(key).Value
      Else
        Return defaultValue
      End If
    End Get
  End Property

  Public Property IntegerValue(ByVal key As String) As Integer?
    Get
      If Me._valuePair.ContainsKey(key) Then
        Try
          Return Integer.Parse(Me._valuePair(key).Value)
        Catch
        End Try
      End If
      Return Nothing
    End Get
    Set(ByVal value As Integer?)
      If Me._valuePair.ContainsKey(key) Then
        If value IsNot Nothing Then
          Me._valuePair(key).Value = value.ToString
        Else
          Me.Remove(key)
        End If
      ElseIf value.HasValue Then
        Me.Add(key, value.Value)
      End If
    End Set
  End Property

  Public ReadOnly Property IntegerValueNoNull(ByVal key As String, Optional ByVal defaultValue As Integer = 0) As Integer
    Get
      Dim ret? As Integer = Me.IntegerValue(key)
      If ret IsNot Nothing Then
        Return ret
      Else
        Return defaultValue
      End If
    End Get
  End Property

  Public Property LongValue(ByVal key As String) As Long?
    Get
      If Me._valuePair.ContainsKey(key) Then
        Try
          Return Long.Parse(Me._valuePair(key).Value)
        Catch
        End Try
      End If
      Return Nothing
    End Get
    Set(ByVal value As Long?)
      If Me._valuePair.ContainsKey(key) Then
        If value IsNot Nothing Then
          Me._valuePair(key).Value = value.ToString
        Else
          Me.Remove(key)
        End If
      ElseIf value.HasValue Then
        Me.Add(key, value.Value)
      End If
    End Set
  End Property

  Public ReadOnly Property LongValueNoNull(ByVal key As String, Optional ByVal defaultValue As Long = 0) As Long
    Get
      Dim ret? As Long = Me.LongValue(key)
      If ret IsNot Nothing Then
        Return ret
      Else
        Return defaultValue
      End If
    End Get
  End Property

  Public Property BooleanValue(ByVal key As String) As Boolean?
    Get
      Dim ret? As Integer = Me.IntegerValue(key)
      If ret IsNot Nothing Then
        If ret = 0 Then
          Return False
        Else
          Return True
        End If
      Else
        Return Nothing
      End If
    End Get
    Set(ByVal value As Boolean?)
      If Me._valuePair.ContainsKey(key) Then
        If value IsNot Nothing Then
          If value Then
            Me._valuePair(key).Value = "1"
          Else
            Me._valuePair(key).Value = "0"
          End If
        Else
          Me.Remove(key)
        End If
      ElseIf value.HasValue Then
        Me.Add(key, value.Value)
      End If
    End Set
  End Property

  Public ReadOnly Property BooleanValueNoNull(ByVal key As String, Optional ByVal defaultValue As Boolean = False) As Boolean
    Get
      Dim ret? As Boolean = Me.BooleanValue(key)
      If ret IsNot Nothing Then
        Return ret
      Else
        Return defaultValue
      End If
    End Get
  End Property

  Public ReadOnly Property ContainsKey(ByVal key As String)
    Get
      Return Me._valuePair.ContainsKey(key)
    End Get
  End Property

  Friend Property TriStateValue(ByVal key As String) As Boolean
    Get
      Return Me._valuePair(key).Tristate
    End Get
    Set(ByVal value As Boolean)
      Me._valuePair(key).Tristate = value
    End Set
  End Property

End Class
